package com.yuanss.backenddemo.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.yuanss.backenddemo.common.HttpStatus;
import com.yuanss.backenddemo.common.R;
import com.yuanss.backenddemo.constant.Constant;
import com.yuanss.backenddemo.constant.SysUserConstant;
import com.yuanss.backenddemo.dao.SysMenuDao;
import com.yuanss.backenddemo.dao.SysRoleDao;
import com.yuanss.backenddemo.dao.SysRoleMenuDao;
import com.yuanss.backenddemo.entity.po.SysRole;
import com.yuanss.backenddemo.entity.po.SysRoleMenu;
import com.yuanss.backenddemo.entity.po.SysUser;
import com.yuanss.backenddemo.entity.vo.req.AddRoleReqVo;
import com.yuanss.backenddemo.entity.vo.req.QueryRoleReqVo;
import com.yuanss.backenddemo.entity.vo.rsp.QueryRoleDetailRsp;
import com.yuanss.backenddemo.service.RoleService;
import com.yuanss.backenddemo.utils.ShiroUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author yuanss
 * @version 1.0
 * @description 权限服务实现曾
 * @date 2024/6/9 08:35:21
 */
@Service
public class RoleServiceImpl implements RoleService {

    @Resource
    private SysRoleDao sysRoleDao;

    @Resource
    private SysRoleMenuDao sysRoleMenuDao;

    @Resource
    private SysMenuDao sysMenuDao;

    @Override
    public R<List<SysRole>> queryAll(QueryRoleReqVo queryRoleReqVo) {
        // 如果页码为0，则查询所有，否则分页查询
        List<SysRole> sysRoles;
        R<List<SysRole>> result = new R<>();
        if (queryRoleReqVo != null && queryRoleReqVo.getPageNum().equals(0)) {
            // 查询状态为启用的
            queryRoleReqVo.setStatus(Constant.status.NORMAL);
            sysRoles = sysRoleDao.queryAllByLimit(queryRoleReqVo);
        } else {
            PageHelper.startPage(queryRoleReqVo.getPageNum(), queryRoleReqVo.getPageSize());
            sysRoles = sysRoleDao.queryAllByLimit(queryRoleReqVo);
            PageInfo<SysRole> pageInfo = PageInfo.of(sysRoles);
            result.setTotal(pageInfo.getTotal());
        }
        result.setCode(HttpStatus.SUCCESS);
        result.setData(sysRoles);
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public R addRole(AddRoleReqVo sysRole) {
        // 添加角色信息
        sysRole.setDelFlag(Constant.delFlag.NORMAL);
        sysRoleDao.insert(sysRole);
        // 添加角色菜单信息
        List<Long> menuIds = sysRole.getMenuIds();
        if (ObjectUtils.isNotEmpty(menuIds)) {
            List<SysRoleMenu> sysRoleMenus = makeSysRoleMenus(sysRole.getRoleId(), menuIds);
            sysRoleMenuDao.insertBatch(sysRoleMenus);
        }
        return R.success("添加角色成功");
    }

    /**
     * 构建角色菜单信息（前端el-tree组件存在父节点下所有子节点不是全部被选中，父节点无法被选中的情况）
     *
     * @param roleId  角色id
     * @param menuIds 菜单id集合
     * @return 角色菜单信息集合
     */
    private List<SysRoleMenu> makeSysRoleMenus(Long roleId, List<Long> menuIds) {
//        // 先处理菜单信息
//        List<SysMenu> sysMenus = sysMenuDao.listByMenuIds(menuIds);
//        List<Long> addIds = new ArrayList<>();
//        sysMenus.forEach(sysMenu -> {
//            if (!ROOT_MENU_ID.equals(sysMenu.getParentId())
//                    && !menuIds.contains(sysMenu.getParentId())
//                    && !addIds.contains(sysMenu.getParentId())
//            ) {
//                addIds.add(sysMenu.getParentId());
//            }
//        });
//        menuIds.addAll(addIds);
        return menuIds.stream().map(menuId -> {
            SysRoleMenu sysRoleMenu = new SysRoleMenu();
            sysRoleMenu.setRoleId(roleId);
            sysRoleMenu.setMenuId(menuId);
            return sysRoleMenu;
        }).collect(Collectors.toList());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public R deleteRole(Long roleId) {
        // 删除角色信息
        sysRoleDao.deleteById(roleId);
        // 删除角色菜单信息
        sysRoleMenuDao.deleteById(roleId);
        return R.success("删除角色信息成功");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public R updateRole(AddRoleReqVo sysRole) {
        // 更新角色信息
        sysRole.setUpdateBy(ShiroUtils.getUserId());
        sysRole.setUpdateTime(new Date());
        sysRoleDao.update(sysRole);
        // 更新角色菜单信息
        List<Long> menuIds = sysRole.getMenuIds();
        if (ObjectUtils.isNotEmpty(menuIds)) {
            // 删除角色菜单信息
            sysRoleMenuDao.deleteById(sysRole.getRoleId());
            // 添加角色菜单信息
            List<SysRoleMenu> sysRoleMenus = makeSysRoleMenus(sysRole.getRoleId(), menuIds);
            sysRoleMenuDao.insertBatch(sysRoleMenus);
        }
        return R.success("更新角色信息成功");
    }

    @Override
    public R<QueryRoleDetailRsp> queryRole(Long roleId) {
        // 查询角色信息
        SysRole queryById = sysRoleDao.queryById(roleId);
        if (ObjectUtils.isEmpty(queryById)) {
            return R.error("角色不存在");
        }
        // 查询角色菜单信息
        List<Long> menuIds = sysRoleMenuDao.queryMenuIdByRoleIds(Collections.singletonList(roleId));
        // 封装返回数据
        QueryRoleDetailRsp queryRoleDetailRsp = new QueryRoleDetailRsp();
        BeanUtils.copyProperties(queryById, queryRoleDetailRsp);
        queryRoleDetailRsp.setMenuIds(menuIds);
        return R.success(queryRoleDetailRsp);
    }

    /**
     * 角色名称唯一性校验
     *
     * @param sysRole 角色信息
     * @return true：唯一，false：不唯一
     */
    @Override
    public boolean checkRoleNameUnique(SysRole sysRole) {
        SysRole queryByName = sysRoleDao.queryByName(sysRole.getRoleName());
        if (ObjectUtils.isEmpty(queryByName)) {
            return false;
        }
        return !queryByName.getRoleId().equals(sysRole.getRoleId());
    }

    /**
     * 角色编码唯一性校验
     *
     * @param sysRole 角色信息
     * @return true：唯一，false：不唯一
     */
    @Override
    public boolean checkRoleCodeUnique(SysRole sysRole) {
        SysRole queryByCode = sysRoleDao.queryByCode(sysRole.getRoleCode());
        if (ObjectUtils.isEmpty(queryByCode)) {
            return true;
        }
        return queryByCode.getRoleId().equals(sysRole.getRoleId());
    }

    @Override
    public R changeStatus(Long roleId) {
        SysRole sysRole = sysRoleDao.queryById(roleId);
        if(ObjectUtils.isEmpty(sysRole)){
            return R.error("角色不存在");
        }
        // 状态转换
        if(SysUserConstant.status.NORMAL.equals(sysRole.getStatus())){
            sysRole.setStatus(SysUserConstant.status.DISABLE);
        }else{
            sysRole.setStatus(SysUserConstant.status.NORMAL);
        }
        sysRole.setUpdateBy(ShiroUtils.getUserId());
        sysRole.setUpdateTime(new Date());
        sysRoleDao.update(sysRole);
        return R.success("用户状态已修改");
    }
}
